<?php

namespace App\Libs\Vm;


use Exception;
use TencentCloud\Common\Credential;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Cvm\V20170312\CvmClient;
use TencentCloud\Cvm\V20170312\Models\DescribeInstancesRequest;
use TencentCloud\Cvm\V20170312\Models\DescribeRegionsRequest;
use TencentCloud\Cvm\V20170312\Models\RebootInstancesRequest;
use TencentCloud\Cvm\V20170312\Models\StartInstancesRequest;
use TencentCloud\Cvm\V20170312\Models\StopInstancesRequest;

class CvmLib
{
    /**
     * 使用AK&SK初始化账号Client
     * @return CvmClient Client
     */
    public static function createClient($regionId){
        $cred = new Credential(config("vm.tencent_cloud_access_key_id"), config("vm.tencent_cloud_access_key_secret"));
        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        $httpProfile = new HttpProfile();
        $httpProfile->setEndpoint("cvm.tencentcloudapi.com");
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        $clientProfile = new ClientProfile();
        $clientProfile->setHttpProfile($httpProfile);
        // 实例化要请求产品的client对象,clientProfile是可选的
        return new CvmClient($cred, $regionId, $clientProfile);
    }

    /**
     * Note - ECS实例属性信息
     * DateTime 2025/2/10 16:10
     * User Admin
     * @param $regionId
     * @param $instanceId
     * @return array
     */
    public static function info($regionId, $instanceId)
    {
        try {
            $client = self::createClient($regionId);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new DescribeInstancesRequest();
            $params = array(
                "instanceIds" => [$instanceId],
                "Filters" => array(
                    array(
                        "Name" => "instance-id",
                        "Values" => [$instanceId]
                    )
                ),
                // "Offset" => 0,
                // "Limit" => 1
            );
            $req->fromJsonString(json_encode($params));
            // 返回的resp是一个DescribeInstancesResponse的实例，与请求对象对应
            $resp = $client->DescribeInstances($req);
            logInfo('cvm_info',$resp->toJsonString());
            // 输出json格式的字符串回包
            $response = $resp->getInstanceSet();
            logInfo('cvm_info',$response[0]);
            return [
                'InstanceId' => $response[0]->InstanceId ?? '',
                'Status' => strtolower($response[0]->InstanceState ?? ''),
                'InstanceName' => $response[0]->InstanceName ?? '',
                'Ip' => $response[0]->PublicIpAddresses[0] ?? ($response[0]->PrivateIpAddresses[0] ?? ''),
            ];
            // return $resp->toJsonString();
        } catch (\Throwable $error) {
            if (!($error instanceof TencentCloudSDKException)) {
                $error = new TencentCloudSDKException([], $error->getMessage(), $error->getCode(), $error);
            }
            logInfo('cvm_info',['错误' => $error->getMessage(),'诊断地址' => $error->data["Recommend"] ?? 'url']);
            return [];
        }
    }

    /**
     * Note - ECS实例列表
     * DateTime 2025/2/6 10:37
     * User Admin
     */
    public static function list($regionId, $instanceId){
        try {
            $client = self::createClient($regionId);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new DescribeInstancesRequest();
            $params = array(
                "instanceIds" => [$instanceId]
            );
            $req->fromJsonString(json_encode($params));
            // 返回的resp是一个DescribeInstancesResponse的实例，与请求对象对应
            $resp = $client->DescribeInstances($req);
            // 输出json格式的字符串回包
            logInfo('cvm_list',$resp->toJsonString());
            return $resp->toJsonString();
        }  catch (\Throwable $error) {
            if (!($error instanceof TencentCloudSDKException )) {
                $error = new TencentCloudSDKException ([], $error->getMessage(), $error->getCode(), $error);
            }
            // var_dump($error->message);
            logInfo('cvm_list',['错误' => $error->getMessage(),'诊断地址' => $error->data["Recommend"] ?? 'url']);
        }
        return false;
    }

    /**
     * Note - ECS实例 启动
     * DateTime 2025/2/6 11:43
     * User Admin
     * @param $regionId
     * @param $instanceId
     * @return bool
     */
    public static function start($regionId,$instanceId){

        try {
            $client = self::createClient($regionId);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new StartInstancesRequest();

            $params = array(
                "InstanceIds" => [$instanceId]
            );
            $req->fromJsonString(json_encode($params));

            // 返回的resp是一个StartInstancesResponse的实例，与请求对象对应
            $resp = $client->StartInstances($req);
            logInfo('cvm_start',$resp->getRequestId());
            if ($resp->getRequestId()){
                return true;
            }

        } catch (\Throwable $error) {
            if (!($error instanceof TencentCloudSDKException )) {
                $error = new TencentCloudSDKException ([], $error->getMessage(), $error->getCode(), $error);
            }
            // var_dump($error->message);
            logInfo('cvm_start',['错误' => $error->getMessage(),'诊断地址' => $error->data["Recommend"] ?? 'url']);
        }
        return false;
    }

    /**
     * Note - ECS实例 重启
     * DateTime 2025/2/6 11:43
     * User Admin
     * @param $regionId
     * @param $instanceId
     * @return bool
     */
    public static function restart($regionId,$instanceId){
        try {
            $client = self::createClient($regionId);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new RebootInstancesRequest();

            $params = array(
                "InstanceIds" => [$instanceId]
            );
            $req->fromJsonString(json_encode($params));

            // 返回的resp是一个RebootInstancesResponse的实例，与请求对象对应
            $resp = $client->RebootInstances($req);
            // 输出json格式的字符串回包
            logInfo('cvm_restart',$resp->getRequestId());
            if ($resp->getRequestId()){
                return true;
            }
        } catch (\Throwable $error) {
            if (!($error instanceof TencentCloudSDKException )) {
                $error = new TencentCloudSDKException ([], $error->getMessage(), $error->getCode(), $error);
            }
            logInfo('cvm_restart',['错误' => $error->getMessage(),'诊断地址' => $error->data["Recommend"] ?? 'url']);
        }
        return false;
    }


    /**
     * Note - ECS实例 停机
     * DateTime 2025/2/6 11:43
     * User Admin
     * @param $regionId
     * @param $instanceId
     * @return bool
     */
    public static function shoutDown($regionId,$instanceId){
        try {
            $client = self::createClient($regionId);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new StopInstancesRequest();
            $params = array(
                "InstanceIds" => [$instanceId]
            );
            $req->fromJsonString(json_encode($params));

            // 返回的resp是一个StopInstancesResponse的实例，与请求对象对应
            $resp = $client->StopInstances($req);
            // 输出json格式的字符串回包
            // print_r($resp->toJsonString());
            logInfo('cvm_shotDown',$resp->getRequestId());
            if ($resp->getRequestId()){
                return true;
            }
        } catch (Exception $error) {
            if (!($error instanceof TencentCloudSDKException)) {
                $error = new TencentCloudSDKException([], $error->getMessage(), $error->getCode(), $error);
            }
            logInfo('cvm_shoutDown',['错误' => $error->getMessage(),'诊断地址' => $error->data["Recommend"] ?? 'url']);
        }
        return false;
    }

    public static function regionList()
    {
        try {
            $client = self::createClient('');
            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new DescribeRegionsRequest();
            $params = array(
            );
            $req->fromJsonString(json_encode($params));

            // 返回的resp是一个StopInstancesResponse的实例，与请求对象对应
            $resp = $client->DescribeRegions($req);
            // 输出json格式的字符串回包
            // print_r($resp->toJsonString());
            logInfo('cvm_regionlist',$resp->getRegionSet());
            if ($resp->getRegionSet()){
                return $resp->getRegionSet();
            }
        } catch (Exception $error) {
            if (!($error instanceof TencentCloudSDKException)) {
                $error = new TencentCloudSDKException([], $error->getMessage(), $error->getCode(), $error);
            }
            logInfo('cvm_shoutDown',['错误' => $error->getMessage(),'诊断地址' => $error->data["Recommend"] ?? 'url']);
        }
        return [];

    }

}
